﻿using SuperSocket.Common;
using SuperSocket.SocketBase.Protocol;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Windows.Forms.AxHost;

namespace WPF_SocketServer_Demo.ReceiveFilter
{
    public abstract class ReceiveFilterHelper<TRequestInfo> : ReceiveFilterBase<TRequestInfo>
            where TRequestInfo : IRequestInfo
    {
        private SearchMarkState<byte> m_BeginSearchState;
        private SearchMarkState<byte> m_EndSearchState;
        private bool m_FoundBegin = false;
        protected TRequestInfo NullRequestInfo = default(TRequestInfo);
        /// <summary>
        /// 初始化实例
        /// </summary>
        protected ReceiveFilterHelper()
        {

        }
        /// <summary>
        /// 过滤指定的会话
        /// </summary>
        /// <param name="readBuffer">数据缓存</param>
        /// <param name="offset">数据起始位置</param>
        /// <param name="length">缓存长度</param>
        /// <param name="toBeCopied"></param>
        /// <param name="rest"></param>
        /// <returns></returns>
        public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
        {
            rest = 0;
            int searchEndMarkOffset;
            int searchEndMarkLength;

            // 定义起始标记和结束标记
            byte[] startMark = new byte[] { 0x01 }; // 起始标记，假设是数据的第一个字节
            byte[] endMark = new byte[] { 0xff }; // 结束标记，假设是 0xff
            m_BeginSearchState = new SearchMarkState<byte>(startMark);
            m_EndSearchState = new SearchMarkState<byte>(endMark);
            int prevMatched = 0;
            int totalParsed = 0;

            // 如果尚未找到起始标记
            if (!m_FoundBegin)
            {
                prevMatched = m_BeginSearchState.Matched; // 获取之前匹配的起始标记长度
                int pos = readBuffer.SearchMark(offset, length, m_BeginSearchState, out totalParsed);

                if (pos < 0) // 如果没有找到起始标记
                {
                    if (prevMatched > 0 || (m_BeginSearchState.Matched > 0 && length != m_BeginSearchState.Matched))
                    {
                        // 如果之前匹配的标记长度大于0，或者起始标记的匹配长度不对，则设置状态为错误
                        State = FilterState.Error;
                        return NullRequestInfo;
                    }

                    return NullRequestInfo; // 返回空请求信息
                }
                else
                {
                    if (pos != offset)
                    {
                        // 如果起始标记的位移位置不对，则设置状态为错误
                        State = FilterState.Error;
                        return NullRequestInfo;
                    }
                }

                m_FoundBegin = true; // 标记已经找到起始标记
                searchEndMarkOffset = pos + m_BeginSearchState.Mark.Length - prevMatched;
                if (offset + length < searchEndMarkOffset)
                {
                    // 数据长度不足以包含完整的起始标记和数据
                    AddArraySegment(m_BeginSearchState.Mark, 0, m_BeginSearchState.Mark.Length, false);
                    return NullRequestInfo;
                }
                searchEndMarkLength = offset + length - searchEndMarkOffset;
            }
            else
            {
                // 如果已经找到起始标记，则从当前位置开始处理数据
                searchEndMarkOffset = offset;
                searchEndMarkLength = length;
            }

            while (true)
            {
                var prevEndMarkMatched = m_EndSearchState.Matched;
                var parsedLen = 0;
                var endPos = readBuffer.SearchMark(searchEndMarkOffset, searchEndMarkLength, m_EndSearchState, out parsedLen);

                if (endPos < 0)
                {
                    // Handle incomplete data
                    rest = length;
                    if (prevMatched > 0)
                        AddArraySegment(m_BeginSearchState.Mark, 0, prevMatched, false);
                    AddArraySegment(readBuffer, offset, length, toBeCopied);
                    return NullRequestInfo;
                }

                // Process data
                totalParsed = endPos - searchEndMarkOffset + m_EndSearchState.Mark.Length;
                byte[] commandData = new byte[BufferSegments.Count + prevMatched + totalParsed];

                if (BufferSegments.Count > 0)
                    BufferSegments.CopyTo(commandData, 0, 0, BufferSegments.Count);

                if (prevMatched > 0)
                    Array.Copy(m_BeginSearchState.Mark, 0, commandData, BufferSegments.Count, prevMatched);

                Array.Copy(readBuffer, searchEndMarkOffset, commandData, BufferSegments.Count + prevMatched, totalParsed);

                var requestInfo = ProcessMatchedRequest(commandData, 0, commandData.Length);

                Reset();
                return requestInfo;
            }
        }
        /// <summary>
        /// Processes the matched request.
        /// </summary>
        /// <param name="readBuffer">The read buffer.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="length">The length.</param>
        /// <returns></returns>
        protected abstract TRequestInfo ProcessMatchedRequest(byte[] readBuffer, int offset, int length);

        /// <summary>
        /// Resets this instance.
        /// </summary>
        public override void Reset()
        {
            m_BeginSearchState.Matched = 0;
            m_EndSearchState.Matched = 0;
            m_FoundBegin = false;
            base.Reset();
        }
    }
}
